#
#	genx_application.py
#
#	David Janes
#	2008.08.16
#
#	GenX - search, create and insert structured data
#

import sys
sys.path.append('/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/simplejson-1.9.2-py2.5.egg')

import types
import re
import pprint
import cgi
import md5
import imp
import os
import os.path
import traceback

import wsgiref.handlers
import wsgiref.headers

import bm_cfg
bm_cfg.cfg.initialize()

import genx_index
import genx_search
import genx_parameters
import genx_extensions
import genx_cfg
import genx_helpers
import genx_store
import genx_html
import genx_open

from bm_log import Log

ACTION_INDEX = "index"
ACTION_SEARCH = "search"
ACTION_OPEN = "open"
ACTION_OPEN_NEXT = "open-next"
ACTION_OPEN_PREV = "open-prev"
ACTIONS = [
	ACTION_INDEX,
	ACTION_SEARCH,
	ACTION_OPEN,
	ACTION_OPEN_NEXT,
	ACTION_OPEN_PREV,
]

class SemanticForms(
	genx_index.IndexMixin, 
	genx_search.SearchMixin,
	genx_extensions.ExtensionsMixin,
	genx_open.OpenMixin,
	genx_store.StoreMixin,
	genx_html.HTMLMixin,
	):
	def __init__(self, environ, start_response):
		self.environ = environ
		self.start = start_response
		self.headers = wsgiref.headers.Headers([])

		self.searchds = []
		self.searchdd = {}
		self.qitemds = None

		genx_index.IndexMixin.__init__(self)
		genx_search.SearchMixin.__init__(self)
		genx_extensions.ExtensionsMixin.__init__(self)
		genx_store.StoreMixin.__init__(self)
		genx_html.HTMLMixin.__init__(self)

	def __iter__(self):
		#
		#	Parse the parameters
		#	- p_action: what to do, as defined by ACTION_
		#		ACTION_INDEX: the main page: query field + action selection
		#		ACTION_SEARCH: search results
		#		ACTION_OPEN: the selected result in a form (plus doing somthing with it)
		#	- p_mid: the module ID -- the name (i.e. directory) of an extension -- such as "freebase.music-artist"
		#	- p_iid
		#	- p_qid
		#	- p_callbacks
		#	- p_search: the current search
		#	- p_short: the _original_ search -- i.e. if this is involved with an original query
		#
		self.p = genx_parameters.Parameters(self.environ.get('QUERY_STRING', ''))

		self.p_action = self.p.GetAsEnum("action", values = ACTIONS) or ''
		self.p_search = self.p.GetAsString("search") or ''
		self.p_original = self.p.GetAsString("original") or ''
		self.p_mid = self.p.GetAsString("mid") or ''
		self.p_iid = self.p.GetAsString("iid") or ''
		self.p_qid = self.p.GetAsString("qid") or md5.new("%s/%s" % ( self.p_mid, self.p_search, )).hexdigest()
		self.p_callbacks = self.p.GetAsString("callbacks") or 'js.callbacks'

		#
		#	Load the query results
		#
		if self.p_qid:
			self.qitemds = self.LoadAsJson(iid = "query")
			if not self.qitemds:
				self.p_qid = ""

		if not self.p_qid:
			self.p_qid = md5.new("%s/%s" % ( self.p_mid, self.p_search, )).hexdigest()

		#
		#	Do the action
		#
		if self.p_action == ACTION_INDEX:
			if not self.p_original:
				self.p_original = self.p_search

			return	self.ActionIndex()
		elif self.p_action == ACTION_SEARCH:
			if not self.p_search:
				return	self.ActionIndex()

			searchd = self.searchdd.get(self.p_mid)
			pprint.pprint(( self.p_mid, searchd ), sys.stderr)
			if not searchd:
				return	self.ActionIndex()
				
			return	self.ActionSearch(searchd)
		elif self.p_action in [ ACTION_OPEN, ACTION_OPEN_NEXT, ACTION_OPEN_PREV ]:
			if not self.p_iid:
				return	self.ActionIndex()

			if not self.p_mid:
				return	self.ActionIndex()

			#
			#	page through the results
			#
			if self.p_action in [ ACTION_OPEN_NEXT, ACTION_OPEN_PREV ] and self.qitemds:
				index = None
				count = -1
				for qitemd in self.qitemds:
					count += 1
					if qitemd[genx_helpers.KEY_IID] == self.p_iid:
						index = count
						break

				if index != None:
					if self.p_action == ACTION_OPEN_NEXT:
						self.p_iid = self.qitemds[(index + 1) % len(self.qitemds)][genx_helpers.KEY_IID]
					elif self.p_action == ACTION_OPEN_PREV:
						self.p_iid = self.qitemds[(index + len(self.qitemds) - 1) % len(self.qitemds)][genx_helpers.KEY_IID]

			searchd = self.searchdd.get(self.p_mid)
			if not searchd:
				return	self.ActionIndex()
				
			return	self.ActionOpen(searchd)
		else:
			return	self.ActionIndex()

if __name__ == '__main__':
	wsgiref.handlers.CGIHandler().run(SemanticForms)
